package com.zby.config;

import com.zby.security.filter.JwtAuthenticationFilter;
import io.jsonwebtoken.security.Keys;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

import java.nio.charset.StandardCharsets;
import java.util.List;

@EnableWebSecurity
@Configuration
// 安全配置类
public class SecurityConfig {
    @Autowired
    private JwtAuthenticationFilter jwtAuthenticationFilter;
    
    @Value("${token.secret:123456abcdefghijklmnopqrstuvwxyz}")
    private String jwtSecret;

    @Bean
    public static PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
    
    @Bean
    public JwtDecoder jwtDecoder() {
        // 使用 HMAC256 密钥解码并自动验证 exp、nbf、iat 等声明
        return NimbusJwtDecoder.withSecretKey(
                Keys.hmacShaKeyFor(jwtSecret.getBytes(StandardCharsets.UTF_8))
        ).build();
    }
    
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        // 允许访问
        http.authorizeHttpRequests(auth ->
                                auth.requestMatchers("/user/login",
                                "/user/register", "/doc.html","/user/refresh",
                                "/swagger-ui.html", "/swagger-ui/**",
                                "/swagger-resources/**", "/webjars/**",
                                "/*/api-docs/**","/article/**").permitAll()
                                        //放行所有OPTIONS请求（CORS预检）
                                .requestMatchers(HttpMethod.OPTIONS, "/**").permitAll()
                          // 点赞接口需要认证
//                        .requestMatchers(HttpMethod.POST, "/likes/toggle").authenticated()
                       .anyRequest().authenticated() // 其他路径都需要认证后才能访问
                )
                // .anyRequest().authenticated() // 其他路径都需要认证后才能访问
                //).addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)
                // 禁用表单登录
                .formLogin(AbstractHttpConfigurer::disable)
                // 禁用csrf
                .csrf(AbstractHttpConfigurer::disable)
                .exceptionHandling(ex -> ex
                        .authenticationEntryPoint((request, response, authException) -> {
                            // 所有未认证请求返回 401
                            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
                            response.setContentType("application/json;charset=UTF-8");
                            response.getWriter().write("{\"code\":401,\"msg\":\"Token 已过期或无效，请重新登录\"}");
                        })
                )
                // 启用CORS支持
                .cors(cors -> cors.configurationSource(corsConfigurationSource()))
                // 启用OAuth2资源服务器支持
               // .oauth2ResourceServer(oauth2 -> oauth2.jwt(jwt -> jwt.decoder(jwtDecoder())))
                .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
        ;
        return http.build();
    }

    // 控制台忽略所有请求
    @Bean
    public WebSecurityCustomizer webSecurityCustomizer() {
        return web -> {
            web.debug(true); // 开启安全调试日志
            // 显示所有被忽略的路径（如果有）
            web.ignoring().requestMatchers("/channel/**");
        };
    }

    @Bean
    CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowedOrigins(List.of("http://localhost:3001", "http://localhost:8848"));
        config.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS"));
        config.setAllowedHeaders(List.of("*"));
        config.setExposedHeaders(List.of("Content-Disposition")); // 替换通配符
        config.setAllowCredentials(true);
        config.setMaxAge(1800L);
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config);
        return source;
    }


}